<?php

include_once '../Model/BusStop.php';
include_once '../Model/BusLinePath.php';
include_once '../Model/GPS.php';
include_once '../AtacCommunicator/ACBusWaitingTimes.php';
include_once '../AtacCommunicator/ACBikesStatus.php';
include_once 'Constants.php';
include_once '../Utility/DebugLogs.php';


/**
 * Si occupa di reperire i dati sulle fermate. Chi utilizza questa classe non ha bisogno
 * di sapere come e da dove vengono reperiti questi dati. Questa scelta è stata fatta perchè
 * la fonte di questi dati potrebbe cambiare nelle prossime implementazioni.
 * @author Giuseppe
 *
 */
class InfoManager {
	
	public static $INFOSEPARATOR = '_';
	
	
	function __construct() {
		 
	}
	
	/**
	 * Rende tutte le info sulla fermata con un dato atacID
	 * Se la fermata non viene trovata tra i nostri dati, rende stringa vuota
	 * @param String $atacID
	 * @return String una stringa con le info separate da $INFOSEPARATOR id_nome_lat_long. Stringa se la fermata non viene trovata
	 */
	function getStopInformation($atacID) {
		$info = ""; 
		$conn = mysql_connect(DBHOST, DBUSER, DBPASS);

		if ($conn==FALSE)
			return $info;
		
		mysql_select_db(DBNAME);
		$query = "select * from ".STOPSTABLENAME." where IMPIANTO='".$atacID."';";
		$result = mysql_query($query);
		
		if($result==null)
			return "";
		while($row = mysql_fetch_array($result))
		{
			$info = $row['IMPIANTO'].InfoManager::$INFOSEPARATOR.$row['NOMEFERM'].InfoManager::$INFOSEPARATOR.$row['LAT'].InfoManager::$INFOSEPARATOR.$row['LONG'];
		}
		
		mysql_close($conn);
		
		return $info;
		
	} 
	

	
	function getStops() {
		
		
	 	$conn = mysql_connect(DBHOST, DBUSER, DBPASS); 
		mysql_select_db(DBNAME);
		
		$query = "select * from ".STOPSTABLENAME;
		$result = mysql_query($query);
		
		$stops = array();
		
		while($row = mysql_fetch_array($result))
		{
			$stopName = $row['NOMEFERM'];
			$atacID = $row['IMPIANTO'];
			$lat = $row['LAT'];
			$long = $row['LONG'];
			
			$stop = new BusStop($stopName, $atacID, $lat, $long);

			array_push($stops,$stop);
			
		}

		$bs = new ACBikesStatus($stops);
		
		mysql_close($conn);
		
		return $stops;
		
		
	}
	
	
        /**
         * Si occupa di reperire tutte le informazioni riguardanti la stazione di bike sharing richiesta.
         */
	
	function getBikeSharingStationInformation($stationName) {
		$info = "";

                //mi connetto al server.
		$conn = mysql_connect(DBHOST, DBUSER, DBPASS);

		if ($conn==FALSE)
			return $info;

                //effettuo la query per ottenere nome stazione, indirizzo, latitudine, longitudine.
		mysql_select_db(DBNAME);
		$query = "select * from ".BIKESTATIONSTABLENAME." where STAZIONE='".$stationName."';";
		$result = mysql_query($query);
		
		if($result==null)
			return "";
		while($row = mysql_fetch_array($result))
		{
			$info = $row['STAZIONE'].InfoManager::$INFOSEPARATOR.$row['INDIRIZZO'].InfoManager::$INFOSEPARATOR.$row['LAT'].InfoManager::$INFOSEPARATOR.$row['LONG'];
		}
		//prese le inforazioni necessarie, chiudo la connessione con il db e le ritorno.
		mysql_close($conn);
		
		return $info;
		
	} 

        /*Funzione che prende dal server le informazioni relative a tutte le stazioni
         * di bike sharing e le restituisce.
         */

	function getBikeSharingStations() {
		//mi connetto al server per effettuare la query.
	
	 	$conn = mysql_connect(DBHOST, DBUSER, DBPASS); 
		mysql_select_db(DBNAME);
		
		$query = "select * from ".BIKESTATIONSTABLENAME;
		$result = mysql_query($query);
		//echo mysql_num_rows($query);
		
		$stations = array();
                //per ogni stazione salvo tutte le sue informazioni in un array.
		while($row = mysql_fetch_array($result))
		{
			$stationName = $row['STAZIONE'];
			$address = $row['INDIRIZZO'];
			$lat = $row['LAT'];
			$long = $row['LONG'];
			
			$station = new BikeSharingStation ($stationName, $address, $lat, $long, 0, 0);

			array_push($stations,$station);
			
		}

		mysql_close($conn);
		
		return $stations;
		
		
	}

	/*Funzione che prende dal server le informazioni relative a tutte le stazioni
         * di bike sharing e restituisce un elenco ordinato per distanza da una determinata posizione.
         */
	function getBikeSharingStationsCloserThan($meters, $gpsPosition) {
		$limit = 10;
		if ($gpsPosition instanceOf GPS)
		{
			$conn = mysql_connect(DBHOST, DBUSER, DBPASS); 
			mysql_select_db(DBNAME);
			
			//Se la connessione non va a buon fine, rendi null
			if ($conn == FALSE)
			{
				return NULL;
			}
			
			
			$query = "select * from ".BIKESTATIONSTABLENAME."";
			$result = mysql_query($query);
			
			//Se la query non va a buon fine, rendi null
			if ($result==FALSE)
				return NULL;
			
			
			$stations = array();
			
			//Il calcolo viene fatto in kilometri, quindi devo trasformare i metri in km
			$r = $meters/1000;
			
			
			while($row = mysql_fetch_assoc($result))
			{
				
				$lat = doubleval($row['LAT']);
				$long = doubleval($row['LONG']);
				
				$stationGPS = new GPS($lat,$long);
				
				//echo "<br>Distanza:".$busGPS->distanceFrom($gpsPosition)*1000;
				
				if(($distance=$stationGPS->distanceFrom($gpsPosition)) <= $r) {
	
					$stationName = $row['STAZIONE'];
					$address = $row['INDIRIZZO'];
				
					$station = new BikeSharingStation ($stationName, $address, $stationGPS->getLat(), $stationGPS->getLon(), 0, 0);
					$station->setDistance($distance);
	
					array_push($stations,$station);
				}			
							
			}
			
			mysql_close($conn);
			//Ordino le fermate in base alla vicinanza al mio punto gps
			$sortedStations = $this->sortStations($stations,$gpsPosition);
			
			//rendo solo le prime 10
			if (count($sortedStations) > $limit)
				return array_slice($sortedStations,0,$limit);
			else
				return $sortedStations;
			
		}
		
	}


        /*Funzione che ordina le stazioni per distanza da un punto
         */
	
	private function sortStations($stations, $gps) {
		if (count($stations)==0) return $stations;
		if (count($stations)==1) return $stations;
		
		$high = count($stations);
  		while ($high > 0) 
  		{
    		for ($i=0;$i<$high-1;$i++)
    		{
      			
    			if ($gps->distanceFrom($stations[$i]->getPosition()) > $gps->distanceFrom($stations[$i+1]->getPosition())) { 
        			$tmp = $stations[$i];
        			$stations[$i] = $stations[$i+1]; 
        			$stations[$i+1] = $tmp;
      			}
    		}
    		$high = $high-1;
  		}
		
  		return $stations;
		
	}
	
	function getStopsCloserThan($meters, $gpsPosition) {
		$limit = 10;
		if ($gpsPosition instanceOf GPS)
		{
			$conn = mysql_connect(DBHOST, DBUSER, DBPASS); 
			mysql_select_db(DBNAME);
			
			//Se la connessione non va a buon fine, rendi null
			if ($conn == FALSE)
			{
				return NULL;
			}
			
			
			$query = "select * from ".STOPSTABLENAME."";
			$result = mysql_query($query);
			
			//Se la query non va a buon fine, rendi null
			if ($result==FALSE)
				return NULL;
			
			
			$stops = array();
			
			//Il calcolo viene fatto in kilometri, quindi devo trasformare i metri in km
			$r = $meters/1000;
			
			while($row = mysql_fetch_assoc($result))
			{
				
				$lat = doubleval($row['LAT']);
				$long = doubleval($row['LONG']);
				
				$busGPS = new GPS($lat,$long);
				
				//echo "<br>Distanza:".$busGPS->distanceFrom($gpsPosition)*1000;
				
				if($busGPS->distanceFrom($gpsPosition) <= $r) {
	
					$stopName = $row['NOMEFERM'];
					$atacID = $row['IMPIANTO'];
				
					$stop = new BusStop($stopName, $atacID, $lat, $long);
					$stop->setDistance($busGPS->distanceFrom($gpsPosition));
	
					array_push($stops,$stop);
				}			
							
			}
			
			mysql_close($conn);
			//Ordino le fermate in base alla vicinanza al mio punto gps
			$sortedStops = $this->sortStops($stops,$gpsPosition);
			
			
			/*
			foreach ($sortedStops as $stop)
			{
				echo "<br><br>Nome Fermata:".$stop->getStopName();
				echo "<br><br>Distanza:".$gpsPosition->distanceFrom($stop->getPosition());
			}
			*/
			
			//rendo solo le prime 10
			if (count($sortedStops) > $limit)
				return array_slice($sortedStops,0,$limit);
			else
				return $sortedStops;
			
		}
		
	}
	
	
	private function sortStops($stops, $gps) {
		if (count($stops)==0) return $stops;
		if (count($stops)==1) return $stops;
		
		$high = count($stops);
  		while ($high > 0) 
  		{
    		for ($i=0;$i<$high-1;$i++)
    		{
      			
    			if ($gps->distanceFrom($stops[$i]->getPosition()) > $gps->distanceFrom($stops[$i+1]->getPosition())) { 
        			$tmp = $stops[$i];
        			$stops[$i] = $stops[$i+1]; 
        			$stops[$i+1] = $tmp;
      			}
    		}
    		$high = $high-1;
  		}
		
  		return $stops;
		
	}
	
	public function cacheLinesForStops() {
		
		$logfile = fopen($_SERVER['DOCUMENT_ROOT']."/RMob/iPhone-Server/Log/mycachelog.txt",'a');
		$stops = $this->getStops();
		
		logthis("Total BusStops:".count($stops));
		
		if ($stops!=null)
		{
			
			$pos=0;
			foreach($stops as $stop)
			{
				//echo "<br>Memory: ".memory_get_usage();
				$atacCommunicator = new ACBusWaitingTimes();
				
				$pos++;
				
				
				
				//echo "<br>Stop:".$stop->getAtacID()." - Pos: ".$pos;
				logthis("\n$pos) Stop:".$stop->getAtacID()." - Name:".$stop->getStopName());
				$lines = $atacCommunicator->getLinesForStop($stop);
				logthis("*");
				
				if ($lines!=null)
				{
					foreach ($lines as $line)
					{
						logthis("\tLine:".$line->getLineNumber());
						//echo "<br>Line:".$line->getLineNumber();
						//Elimino le aggiunte del tipo (T) per temporanea
						
						
						//Scrivi nella tabella linea e nella tabella fl
						$this->cacheOneLineForOneStop($line, $stop);
						
						
					}
				}
				
				unset($lines);
				unset($atacCommunicator);
			}
		}
			
	}
	
	
	private function cacheOneLineForOneStop($line, $stop) {
		$conn = mysql_connect(DBHOST, DBUSER, DBPASS);

		if ($conn==FALSE)
			return FALSE;
		
		mysql_select_db(DBNAME);
		$number="";
		$rawLineNumber = $line->getLineNumber();
		if (stristr($rawLineNumber,"(T)"))
		{
			$len= strlen($rawLineNumber);
			$number = substr($rawLineNumber,0,$len-4);
		}
		else
			$number = $rawLineNumber;
		
		//Se non c'� nessun record con quella linea, lo inserisco
		$query = "
		
			REPLACE INTO ".LINETABLENAME."
			SET numeroLinea = '$number'
			
		";
		
		//echo "<br>query per linea=".$query."<br>";
		$result = mysql_query($query);
		

		
		//Scrivo anche sulla tabella di corrispondenza fermata-linea
		$query = "
			REPLACE INTO ".LINEATSTOPTABLENAME."
			SET fermata = '".$stop->getAtacID()."',
			linea = '$number'
		";
		
		//echo "<br>query per fl=".$query."<br>";
		
		$result = mysql_query($query);
		
		mysql_close($conn);
				
	}
	
	
	public function cachePathIDsForLines() {
		
		$logfile = fopen($_SERVER['DOCUMENT_ROOT']."/RMob/iPhone-Server/Log/mycachelog.txt",'a');
		
		//Attento, sono stringhe, non oggetti di tipo BusLine
		$linesNumbers = $this->getLinesNumbers();
		
		logthis("Total lines: ".count($linesNumbers));
		
		$atacCommunicator = new ACBusWaitingTimes();
		
		foreach ($linesNumbers as $number)
		{
			//Inserisci uno sleep prima della chiamata ad atacCommunicator
			$pathIDs = $atacCommunicator->getPathIDsForLineNumber($number);
			
			//if ($pathIDs!=null)
			//	foreach($pathIDs as $pathID)
			//		$this->cacheOnePathIDForOneLine($number,$pathID);
		}
		
	}
	
	private function cacheOnePathIDForOneLine($number,$pathID) {
		
		
		$logfile = fopen($_SERVER['DOCUMENT_ROOT']."/RMob/iPhone-Server/Log/mycachelog.txt",'a');
		logthis("Caching Line:".$number." and pathID:".$pathID);
		//echo "<br>Caching Line:".$number." and pathID:".$pathID;
		
		$conn = mysql_connect(DBHOST, DBUSER, DBPASS);

		if ($conn==FALSE)
			return FALSE;
		
		mysql_select_db(DBNAME);
		
		
		//Se non c'� nessun record con quella linea, lo inserisco
		$query = "
			REPLACE INTO ".PATHTABLENAME."
			SET pathID = '$pathID'		
		";
		
		$result = mysql_query($query);
		
		
		$query = "
			REPLACE INTO ".PATHFORLINETABLENAME."
			SET pathID = '$pathID',
			linea = '$number'
		";
		
		$result = mysql_query($query);
		
		mysql_close($conn);
		
	}
	
	
	private function getLinesNumbers() {
		$conn = mysql_connect(DBHOST, DBUSER, DBPASS);

		if ($conn==FALSE)
			return FALSE;
		
		mysql_select_db(DBNAME);
		
		$query = "
			SELECT * FROM ".LINETABLENAME;;

		//echo "<br>query:".$query;
		
		$result = mysql_query($query);
		$linesNumbers = array();
		while($row = mysql_fetch_array($result))
		{
			$lineNumber = $row['numeroLinea'];
			array_push($linesNumbers,$lineNumber);
		}
		
		return $linesNumbers;
		
		
	}
	
	
	public function cacheStopsForPaths() {
		
		$logfile = fopen($_SERVER['DOCUMENT_ROOT']."/RMob/iPhone-Server/Log/mycachelog.txt",'a');
		$pathIDs = $this->getCachedPaths();
		
		logthis("Total paths: ".count($pathIDs));
		

		$atacCommunicator = new ACBusWaitingTimes();

		foreach($pathIDs as $pathID)
		{
			if ($pathID == "022A")
				$busLinePath = $atacCommunicator->getPath($pathID);
		}
		/*
		foreach ($pathIDs as $pathID) 
		{
			logthis("PathID: $pathID");
			$busLinePath = $atacCommunicator->getPath($pathID);
			if ($busLinePath!=null)
			{
				$stops = $busLinePath->getStops();
				$pos=-1;
				if ($stops!=null)
				foreach ($stops as $stop) {
					$pos++;
					$this->cacheOneStopForOnePathID($stop,$pathID,$pos);
				
				}
				unset($stops);
			}
			unset($busLinePath);
			
		}
		
		
*/		
		
	}
	
	private function cacheOneStopForOnePathID($stop,$pathID,$pos) {
		
		//$logfile = fopen($_SERVER['DOCUMENT_ROOT']."/RMob/iPhone-Server/Log/mycachelog.txt",'a');

		logthis("Pos:".$pos." - Stop:".$stop->getAtacID()." - Name:".$stop->getStopName()." - Pathid:".$pathID);
		//echo "<br>Pos:".$pos." - Stop:".$stop->getAtacID()." - Name:".$stop->getStopName()." - Pathid:".$pathID;
		
		
		$conn = mysql_connect(DBHOST, DBUSER, DBPASS);

		if ($conn==FALSE)
			return FALSE;
		
		mysql_select_db(DBNAME);
		
		
		
		$query = "
		
			REPLACE INTO ".STOPFORPATHTABLENAME."
			SET pathID = '$pathID',
			fermata = '".$stop->getAtacID()."',
			pos = $pos
		";
		
		//logthis($query);
		
		$result = mysql_query($query);
		
		/*
		$query = "
			INSERT INTO ".STOPSTABLENAME."(IMPIANTO,NOMEFERM) 
			VALUES ('".$stop->getAtacID()."','".$stop->getStopName()."')
			ON DUPLICATE KEY UPDATE IMPIANTO=IMPIANTO
		";
		
		$result = mysql_query($query);
		*/
		
	}
	
	
	private function getCachedPaths() {
		
		$conn = mysql_connect(DBHOST, DBUSER, DBPASS);

		if ($conn==FALSE)
			return FALSE;
		
		mysql_select_db(DBNAME);
		
		$query = "
			SELECT * FROM ".PATHTABLENAME;;

		//echo "<br>query:".$query;
		
		$result = mysql_query($query);
		$pathIDs = array();
		while($row = mysql_fetch_array($result))
		{
			$pathID = $row['pathID'];
			array_push($pathIDs,$pathID);
		}
		
		return $pathIDs;
	}
	
	public function getCachedPath($pathID) {
		
		$path = null;
		$conn = mysql_connect(DBHOST, DBUSER, DBPASS);

		if ($conn==FALSE)
			return FALSE;
		
		mysql_select_db(DBNAME);
		
		$query = "
			SELECT pos,".STOPSTABLENAME.".* FROM ".STOPFORPATHTABLENAME.",".STOPSTABLENAME."
			WHERE pathID='".$pathID."' AND
			fermata=IMPIANTO 
			ORDER BY pos ASC
			
			";
		
		//echo $query;

		
		
		$result = mysql_query($query);
		$stops = array();
		while($row = mysql_fetch_array($result))
		{
			$atacID = $row['IMPIANTO'];
			$stopName = $row['NOMEFERM'];
			$long = $row['LONG'];
			$lat = $row['LAT'];
			
			$stop = new BusStop($stopName,$atacID,$lat,$long);
			
			array_push($stops,$stop);
		}
		
		if ($stops!=null)
			$path = new BusLinePath($stops,$pathID);
			
		
		return $path;
	
		
		
		
	}
	
	
	function getLinesForStop($atacID) {
		$conn = mysql_connect(DBHOST, DBUSER, DBPASS);

		if ($conn==FALSE)
			return null;
		
		mysql_select_db(DBNAME);
		
		$query = "
			SELECT linea FROM ".LINEATSTOPTABLENAME."
			WHERE fermata='".$atacID."'";
		
		$result = mysql_query($query);
		$lines = array();
		while($row = mysql_fetch_array($result))
		{
			$lineString = $row['linea'];
			$line = new BusLine($lineString);
			array_push($lines,$line);
		}
		
		return $lines;
		
	}
	
	
	function getPathIDForLineAndDirection($line,$direction) {
		
		$conn = mysql_connect(DBHOST, DBUSER, DBPASS);

		if ($conn==FALSE)
			return null;
		
		mysql_select_db(DBNAME);
		
		$query = "SELECT pathID FROM ".PATHFORLINETABLENAME." WHERE linea=$line";
		
		$result = mysql_query($query);
		$pathIDs = array();

		while($row = @mysql_fetch_array($result))
		{
			$pathIDString = $row['pathID'];
			array_push($pathIDs,$pathIDString);
		}
		$paths = array();
		
		foreach($pathIDs as $pathid){
			$path = $this->getCachedPath($pathid);
			array_push($paths, $path);
		}
		
		foreach($paths as $pathObj) {
			if($pathObj!=null){
				$stop = $pathObj->getFinalDestination();
				if (strcmp($stop->getStopName(),$direction)==0){
					return $pathObj->getBusLinePathID();
				}
			}
		}
		foreach($paths as $pathObj) { //verifico se è un circolare
				if($pathObj!=null){
					$stop = $pathObj->getStartPoint();
				   if (strcmp($stop->getStopName(),$direction)==0){
				   		return $pathObj->getBusLinePathID();
				   }
				}
			}
		return null;
	}

	
	function getPathIDsForLine($line) {
		
		$conn = mysql_connect(DBHOST, DBUSER, DBPASS);

		if ($conn==FALSE)
			return null;
		
		mysql_select_db(DBNAME);
		
		$query = "SELECT pathID FROM ".PATHFORLINETABLENAME." WHERE linea=$line";
		
		$result = mysql_query($query);
		$pathIDs = array();
		while($row = mysql_fetch_array($result))
		{
			$pathIDString = $row['pathID'];
			array_push($pathIDs,$pathIDString);
		}
		
		return $pathIDs;		
		
	}
	
	
	
	
	function debugPath($pathID) {

		$logfile = fopen($_SERVER['DOCUMENT_ROOT']."/RMob/iPhone-Server/Log/mycachelog.txt",'a');		
		$atacCommunicator = new ACBusWaitingTimes();
		$busLinePath = $atacCommunicator->getPath($pathID);
		if ($busLinePath!=null)
		{
			$stops = $busLinePath->getStops();
			$pos=-1;
			if ($stops!=null)
			foreach ($stops as $stop) {
				$pos++;
				//logthis("$pos - ".$stop->getStopName() ."- $pathID");
				
				$this->cacheOneStopForOnePathID($stop,$pathID,$pos);
			
			}
			unset($stops);
		}
		unset($busLinePath);	
	}
	
	
	
	function cleanCache($timelimit) {
		$logfile = fopen($_SERVER['DOCUMENT_ROOT']."/RMob/iPhone-Server/Log/mycachelog.txt",'a');
		
		//********* PATHFORLINETABLENAME
		$query = "select * from ".PATHFORLINETABLENAME."
		where lastupdate < '$timelimit'";
		
		logthis("Cancello le seguenti tuple da".PATHFORLINETABLENAME."\n");
		$result = mysql_query($query);
		while($row = mysql_fetch_array($result))
		{
			$pathid = $row['pathID'];
			$line = $row['linea'];
			$lastupdate = $row['lastupdate'];
			logthis("$pathid - $line - $lastupdate");
		}
		
		$query = "delete from ".PATHFORLINETABLENAME."
		where lastupdate < '$timelimit'";
		$result = mysql_query($query);
		

		//*********** PATHTABLENAME
		$query = "select * from ".PATHTABLENAME."
		where lastupdate < '$timelimit'";
		
		logthis("Cancello le seguenti tuple da".PATHTABLENAME."\n");
		$result = mysql_query($query);
		while($row = mysql_fetch_array($result))
		{
			$pathid = $row['pathID'];
			$lastupdate = $row['lastupdate'];
			logthis("$pathid - $lastupdate");
		}
		
		$query = "delete from ".PATHTABLENAME."
		where lastupdate < '$timelimit'";
		$result = mysql_query($query);
		
		//************ STOPFORPATHTABLENAME
		$query = "select * from ".STOPFORPATHTABLENAME."
		where lastupdate < '$timelimit'";
		
		logthis("Cancello le seguenti tuple da".STOPFORPATHTABLENAME."\n");
		$result = mysql_query($query);
		while($row = mysql_fetch_array($result))
		{
			$pathid = $row['pathID'];
			$stopid = $row['fermata'];
			$pos = $row['pos'];
			$lastupdate = $row['lastupdate'];
			logthis("$pathid - $pos - $stopid - $lastupdate");
		}
		
		$query = "delete from ".STOPFORPATHTABLENAME."
		where lastupdate < '$timelimit'";
		$result = mysql_query($query);
		
		
		
	}


}



?>
